/*
 * Copyright (c) 2007 jNetX.
 * http://www.jnetx.com
 * All rights reserved.
 *
 * This software is the confidential and proprietary information of
 * jNetX. You shall not disclose such Confidential Information and
 * shall use it only in accordance with the terms of the license
 * agreement you entered into with jNetX.
 *
 * $Id$
 */
package com.jnetx.javax.sip.header;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.text.ParseException;

import com.jnetx.javax.sip.util.ByteArrayUtil;

import javax.sip.InvalidArgumentException;

/**
 * @author <a href="mailto:dparhonin@jnetx.ru">Dmitry Parhonin</a>
 * @version $Revision$
 */
public class RAckHeaderParser extends HeaderParserBase<RAckHeaderImpl> {
    private static final Log logger = LogFactory.getLog(ProxyAuthorizationHeaderParser.class);

    protected Log getLogger() {
        return logger;
    }

    public RAckHeaderImpl createLazily(byte[] data, int start, int end) {
        return new RAckHeaderImpl(data, start, end);
    }

    public RAckHeaderImpl[] parse(RAckHeaderImpl header, byte[] data, int start, int end) throws ParseException {
        if (header==null) header = new RAckHeaderImpl();
        final int startOfRSeq = ByteArrayUtil.firstMissing(data, ' ', start, end);
        if (startOfRSeq == -1)
            fail("Cannot parse the RAck header!", start);
        final int endOfRSeq = ByteArrayUtil.firstOccurence(data, ' ', startOfRSeq, end);
        if (endOfRSeq ==-1)
            fail("Cannot parse the RAck header!", startOfRSeq);
        final int rSeq;
        try {
            rSeq = Integer.parseInt(new String(data, startOfRSeq, endOfRSeq - startOfRSeq));
        } catch(Exception ex) {
            fail("Cannot parse the RSeq value!", startOfRSeq);
            throw new ParseException("",0);//fake, the exception is always thrown in the previous statement.
        }
        try {
            header.setRSeqNumber(rSeq);
        } catch (InvalidArgumentException e) {
            fail("Cannot set the RSeq value!", startOfRSeq);
        }
        final int startOfCSeq = ByteArrayUtil.firstMissing(data, ' ', endOfRSeq, end);
        if (startOfCSeq == -1)
            fail("Cannot parse the RAck header!", start);
        final int endOfCSeq = ByteArrayUtil.firstOccurence(data, ' ', startOfCSeq, end);
        if (endOfCSeq ==-1)
            fail("Cannot parse the RAck header!", startOfCSeq);
        final int cSeq;
        try {
            cSeq = Integer.parseInt(new String(data, startOfCSeq, endOfCSeq - startOfCSeq));
        } catch(Exception ex) {
            fail("Cannot parse the CSeq value!", startOfCSeq);
            throw new ParseException("",0);//fake, the exception is always thrown in the previous statement.
        }
        try {
            header.setCSeqNumber(cSeq);
        } catch (InvalidArgumentException e) {
            fail("Cannot set the CSeq value!", startOfCSeq);
        }
        final int startOfMethod = ByteArrayUtil.firstMissing(data, ' ', endOfCSeq);
        final int endOfMethod = ByteArrayUtil.lastMissing(data, ' ', startOfMethod, end) + 1;
        header.setMethod(new String(data, startOfMethod, endOfMethod - startOfMethod));
        return new RAckHeaderImpl[]{header};
    }
}
/*
 * $Log$
 */